﻿/**
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files 
 * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, 
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QDrive.QBClient
{
    using System;
    using System.Linq;
    using System.Xml;
    using System.Xml.Linq;
    using System.Text;

    public class QuickbaseApiException : Exception
    {
        public QuickbaseApiException(int errorCode, string errorText, string content, string action, Uri uri)
        {
            _errorCode = errorCode;
            _errorText = errorText;
            _action = action;
            _content = content;
            _uri = uri;
        }
        static public QuickbaseApiException Create(string content, XDocument document, string action, Uri uri)
        {
            var ec = document.Descendants().Where<XElement>(delegate(XElement p)
            {
                return ((p.NodeType == XmlNodeType.Element) && (p.Name.LocalName == "errcode"));
            }).Select<XElement, string>(delegate(XElement p)
            {
                return p.Value;
            }).FirstOrDefault<string>();
            int errorCode = Int32.Parse(ec);

            if (errorCode != 0)
            {
                string errorText = document.Descendants().Where<XElement>(delegate(XElement p)
                {
                    return ((p.NodeType == XmlNodeType.Element) && (p.Name.LocalName == "errtext"));
                }).Select<XElement, string>(delegate(XElement p)
                {
                    return p.Value;
                }).FirstOrDefault<string>();
                return new QuickbaseApiException(errorCode, errorText, content, action, uri);
            }
            return null;
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder("Error: (");
            sb.Append(_errorCode);
            sb.Append(") ");
            sb.Append(_errorText);
            sb.Append(", Action: ");
            sb.Append(_action);
            sb.Append(", Content:\n");
            if (_content.Length > 1024)
            {
                sb.Append(_content.Substring(0, 1023) + "... (size " + _content.Length + ")");
            }
            else
            {
                sb.Append(_content);
            }
            sb.Append("\n");
            sb.Append(base.ToString());
            return sb.ToString();
        }

        public static void ThrowIfError(XDocument document, string content, string action, Uri uri)
        {
            QuickbaseApiException e = Create(content, document, action, uri);
            if (e != null)
                throw e;
        }

        private string _errorText;

        public string ErrorText
        {
            get { return _errorText; }
            set { _errorText = value; }
        }
        private int _errorCode;

        public int ErrorCode
        {
            get { return _errorCode; }
            set { _errorCode = value; }
        }

        private string _content;

        public string Content
        {
            get { return _content; }
            set { _content = value; }
        }

        private string _action;

        public string Action
        {
            get { return _action; }
            set { _action = value; }
        }

        Uri _uri;

        public Uri Uri
        {
            get { return _uri; }
            set { _uri = value; }
        }

    }
}
